import {
  Injectable,
  BadRequestException,
  Inject,
  forwardRef,
} from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import * as mongoose from 'mongoose';
import { applyPatch as applyUnifiedPatch } from 'diff';

import {
  LcCommit,
  LcFileSnapshot,
  ProjectVersionState,
  LcFileChange,
  FileSnapshot,
  FileChangeWithSide,
} from '../types/commit.type';
import { LcDocument } from '../types/editor.type';
import { LcProject } from '../types/editor.type';
import { EditorService } from './editor.service';
import { ITypeEntity } from '../../superType/types/type/superType.type';
import { getDocumentPath, getTypePath } from './virtual-file-system/utils/source-path';

@Injectable()
export class VersionControlService {
  constructor(
    @InjectModel('LcCommit') private commitModel: Model<LcCommit>,
    @InjectModel('LcFileSnapshot')
    private fileSnapshotModel: Model<LcFileSnapshot>,
    @InjectModel('ProjectVersionState')
    private versionStateModel: Model<ProjectVersionState>,
    @InjectModel('LcFileChange') private fileChangeModel: Model<LcFileChange>,
    @InjectModel('doc') private documentModel: Model<LcDocument>,
    @InjectModel('type') private typeModel: Model<ITypeEntity>,
    @InjectModel('project') private projectModel: Model<LcProject>,
    @Inject(forwardRef(() => EditorService))
    private editorService: EditorService,
  ) {}

  /**
   * 🆕 初始化项目版本控制
   */
  async initializeVersionControl(
    projectId: string,
    userId: number,
  ): Promise<LcCommit> {
    // 检查是否已经初始化
    const existingState = await this.versionStateModel.findOne({ projectId });
    if (existingState) {
      throw new BadRequestException('项目版本控制已经初始化');
    }

    // 生成初始快照 - 不过滤分支，获取所有文档
    const initialSnapshots = await this.editorService.generateFileSnapshots({
      projectId,
      userId,
      // 不传 branch 参数，确保获取所有文档
    });

    // 暂时跳过初始文件副本创建，专注于发布版本功能
    const initialSnapshotIds: string[] = [];

    // 创建初始提交（存快照 + 文件副本）
    const initialCommit = await this.commitModel.create({
      projectId,
      parentCommitId: null,
      message: 'Initial commit - 初始化版本控制',
      author: {
        userId,
        username: await this.getUserName(userId),
      },
      timestamp: Date.now(),
      type: 'development',
      snapshot: initialSnapshots,
      changes: [], // 初始提交没有变更记录
      snapshotIds: initialSnapshotIds, // 🔧 修复：存储所有初始文件的副本ID
      stats: {
        filesChanged: 0,
        additions: initialSnapshots.length,
        modifications: 0,
        deletions: 0,
      },
    });

    // 创建项目版本状态记录
    await this.versionStateModel.create({
      projectId,
      developmentCommitId: initialCommit._id,
      createTime: Date.now(),
      updateTime: Date.now(),
    });

    return initialCommit;
  }

  /**
   * 🆕 创建开发提交
   */
  async createDevelopmentCommit(params: {
    projectId: string;
    message: string;
    userId: number;
  }): Promise<LcCommit> {
    // 获取项目版本状态
    const versionState = await this.getProjectVersionState(params.projectId);
    const lastCommit = versionState.developmentCommitId
      ? await this.commitModel.findById(versionState.developmentCommitId)
      : null;

    // 生成当前快照
    const currentSnapshots = await this.editorService.generateFileSnapshots({
      projectId: params.projectId,
      userId: params.userId,
    });

    // 比对变更
    const lastSnapshots = lastCommit?.snapshot || [];
    const changes = this.editorService.compareFileSnapshots({
      sourceSnapshots: lastSnapshots,
      targetSnapshots: currentSnapshots,
      sourceLabel: 'last-commit',
      targetLabel: 'working',
      mode: 'unidirectional',
    });

    if (changes.length === 0) {
      throw new BadRequestException('没有检测到相对于上次提交的变更');
    }

    // 🔧 新增：为变更添加正确的版本号
    const enrichedChanges = await this.enrichChangesWithVersions(
      params.projectId,
      changes,
    );

    // 🔧 修复：只为变更文件创建副本，提高存储效率
    const snapshotIds = await this.createFileSnapshots(
      enrichedChanges,
      params.projectId,
    );

    // 创建开发提交
    const newCommit = await this.commitModel.create({
      projectId: params.projectId,
      parentCommitId: lastCommit?._id,
      message: params.message,
      author: {
        userId: params.userId,
        username: await this.getUserName(params.userId),
      },
      timestamp: Date.now(),
      type: 'development',
      snapshot: currentSnapshots,
      changes: enrichedChanges, // 🔧 使用增强后的变更
      snapshotIds: snapshotIds,
      stats: this.calculateStats(enrichedChanges), // 🔧 使用增强后的变更计算统计
    });

    // 更新项目版本状态
    await this.versionStateModel.updateOne(
      { projectId: params.projectId },
      {
        developmentCommitId: newCommit._id,
        updateTime: Date.now(),
      },
    );

    return newCommit;
  }

  /**
   * 🆕 创建发布版本
   */
  async createRelease(params: {
    projectId: string;
    version: string;
    description: string;
    fromCommitId?: string;
    userId: number;
  }): Promise<LcCommit> {
    const versionState = await this.getProjectVersionState(params.projectId);
    const baseCommitId =
      params.fromCommitId || versionState.developmentCommitId;

    if (!baseCommitId) {
      throw new BadRequestException('没有可发布的开发版本');
    }

    // 检查版本号是否已存在
    const existingRelease = await this.commitModel.findOne({
      projectId: params.projectId,
      type: 'release',
      'releaseTag.version': params.version,
    });

    if (existingRelease) {
      throw new BadRequestException(`版本 ${params.version} 已存在`);
    }

    const baseCommit = await this.commitModel.findById(baseCommitId);
    if (!baseCommit) {
      throw new BadRequestException('基础提交不存在');
    }

    // 创建发布提交
    const releaseCommit = await this.commitModel.create({
      projectId: params.projectId,
      parentCommitId: baseCommit._id,
      message: `Release ${params.version}: ${params.description}`,
      author: {
        userId: params.userId,
        username: await this.getUserName(params.userId),
      },
      timestamp: Date.now(),
      type: 'release',
      snapshot: baseCommit.snapshot,
      changes: baseCommit.changes, // 🔧 修复：使用基础提交的变更记录
      snapshotIds: baseCommit.snapshotIds,
      releaseTag: {
        version: params.version,
        description: params.description,
        isActive: true,
      },
      stats: baseCommit.stats, // 🔧 修复：使用基础提交的统计信息
    });

    // 将其他发布版本设为非活跃
    await this.commitModel.updateMany(
      {
        projectId: params.projectId,
        type: 'release',
        _id: { $ne: releaseCommit._id },
      },
      { 'releaseTag.isActive': false },
    );

    // 更新项目版本状态
    await this.versionStateModel.updateOne(
      { projectId: params.projectId },
      {
        releaseCommitId: releaseCommit._id,
        releaseVersion: params.version,
        updateTime: Date.now(),
      },
    );

    return releaseCommit;
  }

  /**
   * 🆕 智能发布版本 - 自动处理初始化
   */
  async smartRelease(params: {
    projectId: string;
    version?: string;
    description?: string;
    userId: number;
  }): Promise<LcCommit> {
    // 1. 检查是否已初始化版本控制
    let versionState = await this.versionStateModel.findOne({
      projectId: params.projectId,
    });

    if (!versionState) {
      // 自动初始化版本控制
      await this.initializeVersionControl(params.projectId, params.userId);
      versionState = await this.versionStateModel.findOne({
        projectId: params.projectId,
      });
    } else {
      // 🔧 修复：检查版本状态中引用的提交是否还存在
      await this.validateAndFixVersionState(params.projectId, params.userId);
      // 重新获取修复后的版本状态
      versionState = await this.versionStateModel.findOne({
        projectId: params.projectId,
      });
    }

    // 🔧 修复：检查是否有变更需要发布
    if (versionState?.developmentCommitId) {
      // 检查当前状态与最新开发提交是否有差异
      const currentSnapshots = await this.editorService.generateFileSnapshots({
        projectId: params.projectId,
        userId: params.userId,
      });

      const lastCommit = await this.commitModel.findById(
        versionState.developmentCommitId,
      );
      if (lastCommit) {
        const changes = this.editorService.compareFileSnapshots({
          sourceSnapshots: lastCommit.snapshot,
          targetSnapshots: currentSnapshots,
          sourceLabel: 'last-commit',
          targetLabel: 'current',
          mode: 'unidirectional',
        });

        // 如果没有变更，检查是否已有基于当前开发版本的发布版本
        if (changes.length === 0) {
          const existingRelease = await this.commitModel.findOne({
            projectId: params.projectId,
            type: 'release',
            parentCommitId: versionState.developmentCommitId,
          });

          if (existingRelease) {
            throw new Error('未检测到文件变更');
          }
        } else {
          // 有变更，先创建开发提交
          console.log(`📝 检测到 ${changes.length} 个文件变更，先创建开发提交`);
          console.log(
            `📊 变更详情:`,
            changes.map((c) => `${c.action}: ${c.path}`),
          );
          await this.createDevelopmentCommit({
            projectId: params.projectId,
            message: `Auto commit before release - 发布前自动提交`,
            userId: params.userId,
          });
          // 重新获取版本状态
          versionState = await this.versionStateModel.findOne({
            projectId: params.projectId,
          });
        }
      }
    }

    // 2. 生成默认版本号和描述
    const existingReleases = await this.commitModel
      .find({
        projectId: params.projectId,
        type: 'release',
      })
      .sort({ timestamp: -1 });

    const defaultVersion =
      params.version || this.generateNextVersion(existingReleases);
    const defaultDescription =
      params.description || `自动发布版本 ${defaultVersion}`;

    // 3. 创建发布版本
    return this.createRelease({
      projectId: params.projectId,
      version: defaultVersion,
      description: defaultDescription,
      userId: params.userId,
    });
  }

  /**
   * 🔧 验证并修复版本状态
   */
  private async validateAndFixVersionState(
    projectId: string,
    userId: number,
  ): Promise<void> {
    const versionState = await this.versionStateModel.findOne({ projectId });
    if (!versionState) return;

    let needUpdate = false;
    const updateData: any = {};

    // 检查开发版本提交是否存在
    if (versionState.developmentCommitId) {
      const devCommit = await this.commitModel.findById(
        versionState.developmentCommitId,
      );
      if (!devCommit) {
        console.log(
          `⚠️ 开发版本提交 ${versionState.developmentCommitId} 不存在，将重新初始化`,
        );
        updateData.developmentCommitId = null;
        needUpdate = true;
      }
    }

    // 检查发布版本提交是否存在
    if (versionState.releaseCommitId) {
      const releaseCommit = await this.commitModel.findById(
        versionState.releaseCommitId,
      );
      if (!releaseCommit) {
        console.log(
          `⚠️ 发布版本提交 ${versionState.releaseCommitId} 不存在，将清除发布版本引用`,
        );
        updateData.releaseCommitId = null;
        updateData.releaseVersion = null;
        needUpdate = true;
      }
    }

    // 如果需要更新，执行更新
    if (needUpdate) {
      updateData.updateTime = Date.now();
      await this.versionStateModel.updateOne({ projectId }, updateData);
      console.log(`✅ 版本状态已修复`);
    }

    // 如果开发版本提交不存在，重新初始化
    const updatedState = await this.versionStateModel.findOne({ projectId });
    if (!updatedState?.developmentCommitId) {
      console.log(`🔄 重新初始化版本控制...`);
      // 删除旧的版本状态记录
      await this.versionStateModel.deleteOne({ projectId });
      // 重新初始化
      await this.initializeVersionControl(projectId, userId);
    }
  }

  /**
   * 生成下一个版本号
   */
  private generateNextVersion(existingReleases: LcCommit[]): string {
    if (existingReleases.length === 0) {
      return 'v1.0.0';
    }

    // 获取最新版本号
    const latestRelease = existingReleases[0];
    const latestVersion = latestRelease.releaseTag?.version || 'v1.0.0';

    // 简单的版本号递增逻辑
    const versionMatch = latestVersion.match(/v(\d+)\.(\d+)\.(\d+)/);
    if (versionMatch) {
      const [, major, minor, patch] = versionMatch;
      return `v${major}.${minor}.${parseInt(patch) + 1}`;
    }

    // 如果版本号格式不匹配，使用时间戳
    return `v1.0.${Date.now() % 1000}`;
  }

  /**
   * 获取项目版本状态
   */
  private async getProjectVersionState(
    projectId: string,
  ): Promise<ProjectVersionState> {
    let versionState = await this.versionStateModel.findOne({ projectId });

    if (!versionState) {
      // 如果没有版本状态，创建一个空的
      versionState = await this.versionStateModel.create({
        projectId,
        createTime: Date.now(),
        updateTime: Date.now(),
      });
    }

    return versionState;
  }

  /**
   * 🆕 为所有文件创建副本（用于完整快照）
   */
  // private async createAllFileSnapshots(
  //   snapshots: FileSnapshot[],
  //   projectId: string,
  // ): Promise<string[]> {
  //   const snapshotIds: string[] = [];

  //   for (const snapshot of snapshots) {
  //     // 检查是否已存在相同hash的副本
  //     let existingSnapshot = await this.fileSnapshotModel.findOne({
  //       hash: snapshot.hash,
  //       projectId: projectId,
  //     });

  //     if (existingSnapshot) {
  //       snapshotIds.push(existingSnapshot._id.toString());
  //     } else {
  //       // 获取文件数据
  //       const fileData = await this.getFileDataByPath(snapshot.path, projectId);
  //       if (!fileData) continue;

  //       const newSnapshot = await this.fileSnapshotModel.create({
  //         hash: snapshot.hash,
  //         type: this.getFileType(snapshot.path),
  //         data: fileData,
  //         projectId: projectId,
  //         originalId: fileData._id || fileData.id,
  //         path: snapshot.path,
  //         createTime: Date.now(),
  //         size: this.calculateDataSize(fileData),
  //       });

  //       snapshotIds.push(newSnapshot._id.toString());
  //     }
  //   }

  //   return snapshotIds;
  // }

  /**
   * 创建文件副本（用于变更文件）
   */
  private async createFileSnapshots(
    changes: FileChangeWithSide<any>[],
    projectId: string,
  ): Promise<string[]> {
    const snapshotIds: string[] = [];

    for (const change of changes) {
      if (change.action === 'delete') {
        continue;
      }

      const fileData = await this.getFileDataByPath(change.path, projectId);
      if (!fileData) continue;

      // 🔧 使用 hash 或 update_time 作为 hash
      const fileHash =
        fileData.hash || String(fileData.update_time || Date.now());

      // 检查是否已存在相同hash的副本
      const existingSnapshot = await this.fileSnapshotModel.findOne({
        hash: fileHash,
        projectId: projectId,
      });

      if (existingSnapshot) {
        snapshotIds.push(existingSnapshot._id.toString());
      } else {
        const newSnapshot = await this.fileSnapshotModel.create({
          hash: fileHash,
          type: this.getFileType(change.path),
          data: fileData,
          projectId: projectId,
          originalId: fileData._id,
          path: change.path,
          createTime: Date.now(),
          size: this.calculateDataSize(fileData),
        });

        snapshotIds.push(newSnapshot._id.toString());
      }
    }

    return snapshotIds;
  }

  /**
   * 根据路径获取文件数据
   */
  private async getFileDataByPath(
    path: string,
    projectId: string,
  ): Promise<any> {
    if (path.startsWith('project:')) {
      return await this.projectModel.findById(projectId);
    } else if (this.isDocumentPath(path)) {
      return await this.getDocumentByPath(path, projectId);
    } else if (this.isTypePath(path)) {
      return await this.getTypeByPath(path, projectId);
    }
    return null;
  }

  /**
   * 根据路径获取文档
   */
  private async getDocumentByPath(
    path: string,
    projectId: string,
  ): Promise<LcDocument | null> {
    const allDocs = await this.documentModel.find({ projectId });

    for (const doc of allDocs) {
      if (getDocumentPath(doc) === path) {
        return doc;
      }
    }

    return null;
  }

  /**
   * 根据路径获取类型
   */
  private async getTypeByPath(
    path: string,
    projectId: string,
  ): Promise<ITypeEntity | null> {
    const allTypes = await this.typeModel.find({ projectId });

    for (const type of allTypes) {
      if (getTypePath(type) === path) {
        return type;
      }
    }

    return null;
  }

  /**
   * 判断是否为文档路径
   */
  private isDocumentPath(path: string): boolean {
    return (
      path.includes('/src/pages/') ||
      path.includes('/src/modules/components/') ||
      path.includes('/src/modules/blocks/')
    );
  }

  /**
   * 判断是否为类型路径
   */
  private isTypePath(path: string): boolean {
    return (
      path.includes('/src/apis/') ||
      path.includes('/src/types/') ||
      path.includes('/src/utils/') ||
      path.includes('/src/cloud_functions/') ||
      path.includes('/cloud_functions/')
    );
  }

  /**
   * 获取文件类型
   */
  private getFileType(path: string): 'document' | 'type' | 'project' {
    if (path.startsWith('project:')) return 'project';
    if (this.isDocumentPath(path)) return 'document';
    return 'type';
  }

  /**
   * 计算数据大小
   */
  private calculateDataSize(data: any): number {
    return Buffer.byteLength(JSON.stringify(data), 'utf8');
  }

  /**
   * 计算统计信息
   */
  private calculateStats(changes: FileChangeWithSide<any>[]): any {
    return {
      filesChanged: changes.length,
      additions: changes.filter((c) => c.action === 'add').length,
      modifications: changes.filter((c) => c.action === 'modify').length,
      deletions: changes.filter((c) => c.action === 'delete').length,
    };
  }

  /**
   * 🆕 获取开发版本文件
   */
  async getDevelopmentFiles(projectId: string): Promise<{
    documents: LcDocument[];
    types: ITypeEntity[];
    project?: LcProject;
  }> {
    const versionState = await this.getProjectVersionState(projectId);

    if (!versionState.developmentCommitId) {
      // 没有版本控制，返回当前数据库中的文件
      return this.getCurrentFiles(projectId);
    }

    return this.getVersionFiles(versionState.developmentCommitId);
  }

  /**
   * 🆕 获取发布版本文件
   */
  async getReleaseFiles(
    projectId: string,
    version?: string,
  ): Promise<{
    documents: LcDocument[];
    types: ITypeEntity[];
    project?: LcProject;
  }> {
    const versionState = await this.getProjectVersionState(projectId);

    let targetCommitId: string;

    if (version) {
      const releaseCommit = await this.commitModel.findOne({
        projectId,
        type: 'release',
        'releaseTag.version': version,
      });

      if (!releaseCommit) {
        throw new BadRequestException(`发布版本 ${version} 不存在`);
      }

      targetCommitId = releaseCommit._id;
    } else {
      if (!versionState.releaseCommitId) {
        throw new BadRequestException('没有发布版本');
      }

      targetCommitId = versionState.releaseCommitId;
    }

    return this.getVersionFiles(targetCommitId);
  }

  /**
   * 🆕 获取指定版本的文件 - 优化方案
   */
  async getVersionFiles(commitId: string): Promise<{
    documents: LcDocument[];
    types: ITypeEntity[];
    project?: LcProject;
  }> {
    const commit = await this.commitModel.findById(commitId);
    if (!commit) {
      throw new BadRequestException('提交不存在');
    }

    const result = {
      documents: [] as LcDocument[],
      types: [] as ITypeEntity[],
      project: undefined as LcProject | undefined,
    };

    // 🔧 优化方案：分别处理变更文件和未变更文件

    // 1. 从副本获取变更文件
    if (commit.snapshotIds.length > 0) {
      const changedSnapshots = await this.fileSnapshotModel.find({
        _id: { $in: commit.snapshotIds },
      });

      for (const snapshot of changedSnapshots) {
        switch (snapshot.type) {
          case 'document':
            result.documents.push(snapshot.data as LcDocument);
            break;
          case 'type':
            result.types.push(snapshot.data as ITypeEntity);
            break;
          case 'project':
            result.project = snapshot.data as LcProject;
            break;
        }
      }
    }

    // 2. 从数据库获取未变更文件（使用 NOT IN 排除变更文件）
    const changedPaths = commit.changes.map((c) => c.path);
    const unchangedDocPaths = commit.snapshot
      .filter(
        (s) => !changedPaths.includes(s.path) && this.isDocumentPath(s.path),
      )
      .map((s) => s.path);
    const unchangedTypePaths = commit.snapshot
      .filter((s) => !changedPaths.includes(s.path) && this.isTypePath(s.path))
      .map((s) => s.path);

    // 批量查询未变更的文档和类型
    const [unchangedDocs, unchangedTypes] = await Promise.all([
      this.getDocumentsByPaths(unchangedDocPaths, commit.projectId),
      this.getTypesByPaths(unchangedTypePaths, commit.projectId),
    ]);

    result.documents.push(...unchangedDocs);
    result.types.push(...unchangedTypes);

    // 如果项目文件未变更，从数据库获取
    if (
      !result.project &&
      !changedPaths.some((p) => p.startsWith('project:'))
    ) {
      result.project = await this.projectModel.findById(commit.projectId);
    }

    return result;
  }

  /**
   * Fallback 方式：向上遍历提交链获取文件
   */
  private async getVersionFilesFallback(commitId: string): Promise<{
    documents: LcDocument[];
    types: ITypeEntity[];
    project?: LcProject;
  }> {
    const result = {
      documents: [] as LcDocument[],
      types: [] as ITypeEntity[],
      project: undefined as LcProject | undefined,
    };

    const processedPaths = new Set<string>();

    // 从目标提交开始向上遍历
    let currentCommit = await this.commitModel.findById(commitId);

    while (currentCommit) {
      // 批量获取当前提交的所有副本
      if (currentCommit.snapshotIds.length > 0) {
        const snapshots = await this.fileSnapshotModel.find({
          _id: { $in: currentCommit.snapshotIds },
        });

        for (const snapshot of snapshots) {
          if (processedPaths.has(snapshot.path)) {
            continue;
          }

          switch (snapshot.type) {
            case 'document':
              result.documents.push(snapshot.data as LcDocument);
              break;
            case 'type':
              result.types.push(snapshot.data as ITypeEntity);
              break;
            case 'project':
              if (!result.project) {
                result.project = snapshot.data as LcProject;
              }
              break;
          }

          processedPaths.add(snapshot.path);
        }
      }

      // 继续向上查找父提交
      currentCommit = currentCommit.parentCommitId
        ? await this.commitModel.findById(currentCommit.parentCommitId)
        : null;
    }

    return result;
  }

  /**
   * 获取当前数据库中的文件
   */
  private async getCurrentFiles(projectId: string): Promise<{
    documents: LcDocument[];
    types: ITypeEntity[];
    project?: LcProject;
  }> {
    const [documents, types, project] = await Promise.all([
      this.documentModel.find({ projectId }),
      this.typeModel.find({ projectId }),
      this.projectModel.findById(projectId),
    ]);

    return {
      documents,
      types,
      project: project || undefined,
    };
  }

  /**
   * 🆕 获取提交历史
   */
  async getCommitHistory(params: {
    projectId: string;
    type?: 'development' | 'release' | 'hotfix';
    limit?: number;
    skip?: number;
  }): Promise<{
    commits: LcCommit[];
    total: number;
    hasMore: boolean;
  }> {
    const query: any = {
      projectId: new mongoose.Types.ObjectId(params.projectId),
    };

    if (params.type) {
      query.type = params.type;
    }

    const total = await this.commitModel.countDocuments(query);
    const commits = await this.commitModel
      .find(query)
      .sort({ timestamp: -1 })
      .skip(params.skip || 0)
      .limit(params.limit || 20)
      .lean();

    return {
      commits,
      total,
      hasMore: total > (params.skip || 0) + (params.limit || 20),
    };
  }

  /**
   * 🆕 获取版本列表
   */
  async getVersionList(projectId: string): Promise<{
    development?: LcCommit;
    releases: LcCommit[];
    currentRelease?: LcCommit;
  }> {
    const versionState = await this.getProjectVersionState(projectId);

    const [developmentCommit, releases] = await Promise.all([
      versionState.developmentCommitId
        ? this.commitModel.findById(versionState.developmentCommitId)
        : null,
      this.commitModel
        .find({
          projectId,
          type: 'release',
        })
        .sort({ timestamp: -1 }),
    ]);

    const currentRelease = releases.find((r) => r.releaseTag?.isActive);

    return {
      development: developmentCommit || undefined,
      releases,
      currentRelease,
    };
  }

  /**
   * 🆕 获取工作区状态（类似 git status）
   * 比对当前工作区与上次提交的差异，但不创建提交
   */
  async getWorkingStatus(params: {
    projectId: string;
    userId: number;
    compareWith?: 'development' | 'release'; // 比对目标：开发版本或发布版本
  }): Promise<{
    hasChanges: boolean;
    changes: FileChangeWithSide<any>[];
    stats: {
      added: number;
      modified: number;
      deleted: number;
      total: number;
    };
    baseCommit?: any;
    baseCommitType?: 'development' | 'release';
  }> {
    const { projectId, userId, compareWith = 'development' } = params;
    console.log('getWorkingStatus', compareWith);
    // 获取项目版本状态
    const versionState = await this.getProjectVersionState(projectId);
    console.log('versionState: ', versionState);

    // 确定比对基准
    let baseCommit: LcCommit | null = null;
    let baseCommitType: 'development' | 'release' | undefined;

    if (compareWith === 'release') {
      // 与最新发布版本比对
      console.log(`[getWorkingStatus] 查找发布版本, projectId: ${projectId}`);
      baseCommit = await this.commitModel
        .findOne({
          projectId,
          type: 'release',
        })
        .sort({ timestamp: -1 });
      baseCommitType = 'release';
      console.log(
        `[getWorkingStatus] 找到发布版本: ${
          baseCommit ? baseCommit._id : 'null'
        }, message: ${baseCommit?.message || 'null'}`,
      );
    } else {
      // 与开发版本比对
      console.log(
        `[getWorkingStatus] 查找开发版本, projectId: ${projectId}, developmentCommitId: ${versionState.developmentCommitId}`,
      );
      if (versionState.developmentCommitId) {
        baseCommit = await this.commitModel.findById(
          versionState.developmentCommitId,
        );
        baseCommitType = 'development';
        console.log(
          `[getWorkingStatus] 找到开发版本: ${
            baseCommit ? baseCommit._id : 'null'
          }, message: ${baseCommit?.message || 'null'}`,
        );
      } else {
        console.log(`[getWorkingStatus] 没有开发版本ID`);
      }
    }

    // 生成当前工作区快照
    const currentSnapshots = await this.editorService.generateFileSnapshots({
      projectId,
      userId,
    });
    console.log('currentSnapshots: ', currentSnapshots);

    // 如果没有基准提交，说明是初始状态
    if (!baseCommit) {
      const now = Date.now();
      const changes: FileChangeWithSide<any>[] = currentSnapshots.map((s) => ({
        id: `add_${s.path}_${now}`,
        action: 'add' as const,
        path: s.path,
        version: 1,
        timestamp: s.modify,
        diff: {
          after: { hash: s.hash },
        },
        side: 'target' as const,
        sourceLabel: 'empty',
        targetLabel: 'working',
        target: s,
      })) as any;

      const stats = this.calculateStats(changes);

      console.log('stats: ', stats);

      return {
        hasChanges: currentSnapshots.length > 0,
        changes,
        stats,
      };
    }

    // 比对变更
    const lastSnapshots = baseCommit.snapshot || [];
    const changes = this.editorService.compareFileSnapshots({
      sourceSnapshots: lastSnapshots,
      targetSnapshots: currentSnapshots,
      sourceLabel: baseCommitType === 'release' ? 'release' : 'last-commit',
      targetLabel: 'working',
      mode: 'unidirectional',
    });

    const stats = this.calculateStats(changes);

    // 🔍 调试日志：检查变更记录中的时间戳
    console.log(`[getWorkingStatus] 变更数量: ${changes.length}`);
    if (changes.length > 0) {
      console.log(`[getWorkingStatus] 第一个变更:`, {
        action: changes[0].action,
        path: changes[0].path,
        timestamp: changes[0].timestamp,
        hasTimestamp: !!changes[0].timestamp,
      });
    }

    return {
      hasChanges: changes.length > 0,
      changes,
      stats,
      baseCommit: JSON.parse(JSON.stringify(baseCommit)),
      baseCommitType,
    };
  }

  /**
   * 🆕 批量获取文档（按路径）
   */
  private async getDocumentsByPaths(
    paths: string[],
    projectId: string,
  ): Promise<LcDocument[]> {
    if (paths.length === 0) return [];

    const allDocs = await this.documentModel.find({ projectId });
    const result: LcDocument[] = [];

    for (const path of paths) {
      const doc = allDocs.find((d) => getDocumentPath(d) === path);
      if (doc) {
        result.push(doc);
      }
    }

    return result;
  }

  /**
   * 🆕 批量获取类型（按路径）
   */
  private async getTypesByPaths(
    paths: string[],
    projectId: string,
  ): Promise<ITypeEntity[]> {
    if (paths.length === 0) return [];

    const allTypes = await this.typeModel.find({ projectId });
    const result: ITypeEntity[] = [];

    for (const path of paths) {
      const type = allTypes.find((t) => getTypePath(t) === path);
      if (type) {
        result.push(type);
      }
    }

    return result;
  }

  /**
   * 获取用户名
   */
  private async getUserName(userId: number): Promise<string> {
    // TODO: 从用户服务获取用户名
    return `user_${userId}`;
  }

  /**
   * 🔧 为变更对象添加正确的版本号
   */
  private async enrichChangesWithVersions(
    projectId: string,
    changes: any[],
  ): Promise<any[]> {
    console.log(`🔧 开始为 ${changes.length} 个变更添加版本号...`);

    // 1. 收集所有需要查询的文件路径
    const filePaths = [...new Set(changes.map((c) => c.path))];

    // 2. 批量查询每个文件的最新版本号
    const latestVersions = await Promise.all(
      filePaths.map(async (path) => {
        const change = await this.fileChangeModel
          .findOne({
            projectId,
            path: path,
          })
          .sort({ timestamp: -1 });

        return { path, version: change?.version || 0 };
      }),
    );

    // 3. 构建版本号映射
    const versionMap = new Map<string, number>();
    latestVersions.forEach(({ path, version }) => {
      versionMap.set(path, version);
    });

    console.log(`📊 查询到 ${filePaths.length} 个文件的版本信息`);

    // 4. 为变更对象添加正确的版本号
    const enrichedChanges = changes.map((change) => {
      let version;

      switch (change.action) {
        case 'add':
          version = 1; // 新文件始终是版本 1
          break;
        case 'modify':
          version = (versionMap.get(change.path) || 0) + 1; // 修改版本 +1
          break;
        case 'delete':
          version = versionMap.get(change.path) || 0; // 删除保持当前版本
          break;
        default:
          version = 1;
      }

      const enrichedChange = {
        ...change,
        version,
      };

      console.log(`📝 ${change.action}: ${change.path} -> version ${version}`);

      return enrichedChange;
    });

    console.log(`✅ 版本号增强完成，处理了 ${enrichedChanges.length} 个变更`);

    return enrichedChanges;
  }

  // ==================== 文件变更记录相关方法 ====================

  /**
   * 🆕 获取文件变更历史记录
   */
  async getFileChanges(params: {
    projectId: string;
    path?: string;
    startTime?: number;
    endTime?: number;
    limit?: number;
    skip?: number;
    sortBy?: string;
    sortOrder?: 'asc' | 'desc';
    excludeDocFiles?: boolean; // 🆕 是否排除 .doc 文件
  }): Promise<{
    changes: LcFileChange[];
    total: number;
    hasMore: boolean;
  }> {
    const {
      projectId,
      path,
      startTime,
      endTime,
      limit = 20,
      skip = 0,
      sortBy = 'timestamp',
      sortOrder = 'desc',
      excludeDocFiles = false, // 🆕 默认不排除 .doc 文件
    } = params;

    // 构建查询条件
    const query: any = { projectId };

    if (path) {
      query.path = path;
    }

    if (startTime || endTime) {
      query.timestamp = {};
      if (startTime) query.timestamp.$gte = startTime;
      if (endTime) query.timestamp.$lte = endTime;
    }

    // 🆕 根据参数决定是否排除 .doc 文件
    if (excludeDocFiles) {
      query.path = { $not: /\.doc$/ };
    }

    // 构建排序条件
    const sort: any = {};
    sort[sortBy] = sortOrder === 'desc' ? -1 : 1;

    // 执行查询
    const [changes, total] = await Promise.all([
      this.fileChangeModel
        .find(query)
        .sort(sort)
        .skip(skip)
        .limit(limit)
        .lean(),
      this.fileChangeModel.countDocuments(query),
    ]);

    return {
      changes,
      total,
      hasMore: total > skip + limit,
    };
  }

  /**
   * 🆕 获取文件的下一个版本号
   */
  async getNextVersion(projectId: string, path: string): Promise<number> {
    const count = await this.fileChangeModel.countDocuments({
      projectId,
      path,
    });
    return count + 1;
  }

  /**
   * 🆕 重建指定版本的完整文件内容
   * 核心算法：快照 + 补丁链重建
   */
  async restoreFileVersion(
    projectId: string,
    path: string,
    targetVersion: number,
  ): Promise<string | null> {
    console.log(`[VersionControl] 开始重建文件版本: ${path} v${targetVersion}`);

    // 1. 找到目标版本之前最近的快照
    const baseSnapshot = await this.fileChangeModel
      .findOne({
        projectId,
        path,
        changeType: 'snapshot',
        version: { $lte: targetVersion },
      })
      .sort({ version: -1 })
      .lean();

    if (!baseSnapshot) {
      console.log(`[VersionControl] 未找到基础快照: ${path} v${targetVersion}`);
      return null;
    }

    console.log(
      `[VersionControl] 找到基础快照: v${baseSnapshot.version}, 内容长度: ${
        baseSnapshot.content?.length || 0
      }`,
    );

    let content = baseSnapshot.content || '';
    let actualBaseSnapshot = baseSnapshot;

    // 🔧 如果基础快照内容为空，继续往前找有内容的快照
    if (!content || content.length === 0) {
      console.log(
        `[VersionControl] 基础快照 v${baseSnapshot.version} 内容为空，继续往前查找有效快照`,
      );

      // 查找该快照之前的所有快照，按版本倒序
      const previousSnapshots = await this.fileChangeModel
        .find({
          projectId,
          path,
          changeType: 'snapshot',
          version: { $lt: baseSnapshot.version }, // 查找更早的快照
        })
        .sort({ version: -1 })
        .lean();

      console.log(
        `[VersionControl] 找到 ${previousSnapshots.length} 个更早的快照`,
      );

      // 遍历找到第一个有内容的快照
      let foundValidSnapshot = false;
      for (const snapshot of previousSnapshots) {
        const snapshotContent = snapshot.content || '';
        console.log(
          `[VersionControl] 检查快照 v${snapshot.version}, 内容长度: ${snapshotContent.length}`,
        );

        if (snapshotContent && snapshotContent.length > 0) {
          console.log(
            `[VersionControl] ✅ 找到有效快照: v${snapshot.version} (${snapshotContent.length} 字符)`,
          );
          content = snapshotContent;
          actualBaseSnapshot = snapshot;
          foundValidSnapshot = true;
          break;
        }
      }

      if (!foundValidSnapshot) {
        console.log(`[VersionControl] ❌ 未找到任何有效快照`);
        throw new BadRequestException(
          `版本数据已损坏：文件 ${path} 的所有快照都为空。请在前端重新保存文件以创建有效的版本数据。`,
        );
      }
    }

    // 2. 获取从实际基础快照到目标版本的所有补丁
    const patches = await this.fileChangeModel
      .find({
        projectId,
        path,
        changeType: 'patch',
        version: {
          $gt: actualBaseSnapshot.version, // 🔧 使用实际找到的有效快照版本
          $lte: targetVersion,
        },
      })
      .sort({ version: 1 }) // 按版本号升序
      .lean();

    console.log(
      `[VersionControl] 从 v${actualBaseSnapshot.version} 到 v${targetVersion}，需要应用 ${patches.length} 个补丁`,
    );

    // 3. 依次应用补丁
    const failedPatches: number[] = [];
    for (const patch of patches) {
      if (patch.patch) {
        try {
          const beforeLength = content.length;
          const patchPreview = patch.patch
            .substring(0, 100)
            .replace(/\n/g, '\\n');
          console.log(`[VersionControl] 准备应用补丁 v${patch.version}`);
          console.log(`[VersionControl] 补丁预览: ${patchPreview}...`);

          content = this.applyPatch(content, patch.patch);
          console.log(
            `[VersionControl] ✅ 应用补丁 v${patch.version} 成功: ${beforeLength} -> ${content.length} 字符`,
          );
        } catch (error) {
          failedPatches.push(patch.version);
          console.error(
            `[VersionControl] ❌ 补丁应用失败: ${path} v${patch.version}`,
            error.message,
          );

          // 🔧 补丁应用失败，说明版本数据已损坏，直接抛出错误
          // 让前端知道需要重新生成版本数据
          throw new BadRequestException(
            `版本数据已损坏：补丁 v${patch.version} 应用失败（基础快照: v${actualBaseSnapshot.version}，目标版本: v${targetVersion}）。请在前端重新保存文件以修复版本数据。`,
          );
        }
      }
    }

    console.log(
      `[VersionControl] 文件版本重建完成: ${path} v${targetVersion}, 最终长度: ${content.length}`,
    );
    return content;
  }

  /**
   * 🆕 获取文件的最新内容
   */
  async getLatestFileContent(
    projectId: string,
    path: string,
  ): Promise<string | null> {
    const nextVersion = await this.getNextVersion(projectId, path);
    const latestVersion = nextVersion - 1;

    console.log(`[getLatestFileContent] 文件: ${path}`);
    console.log(`[getLatestFileContent] 下一个版本号: ${nextVersion}`);
    console.log(`[getLatestFileContent] 最新版本号: ${latestVersion}`);

    if (latestVersion <= 0) {
      console.log(`[getLatestFileContent] 没有历史版本，返回 null`);
      return null;
    }

    const content = await this.restoreFileVersion(projectId, path, latestVersion);
    console.log(`[getLatestFileContent] 返回内容长度: ${content?.length || 0}`);

    return content;
  }

  /**
   * 🆕 记录单个文件变更
   */
  async recordFileChange(params: {
    projectId: string;
    path: string;
    action: 'add' | 'modify' | 'delete';
    content?: string;
    previousContent?: string;
    diff?: string; // 🆕 接收前端的 unified diff
    contentHash?: string; // 🆕 接收前端的内容哈希
    author?: string;
    message?: string;
    userId: number;
    forceSnapshot?: boolean; // 🆕 强制创建快照（用于修复损坏的补丁链）
  }): Promise<LcFileChange> {
    const {
      projectId,
      path,
      action,
      content,
      previousContent: providedPreviousContent,
      diff,
      contentHash,
      author,
      message,
      userId,
      forceSnapshot = false, // 🆕 默认不强制快照
    } = params;

    // 计算版本号
    const version = await this.getNextVersion(projectId, path);

    // 🆕 如果没有传 previousContent，且不是首次创建，自动从历史记录获取
    let actualPreviousContent = providedPreviousContent;
    let autoForceSnapshot = false; // 自动强制快照标志

    if (!actualPreviousContent && action === 'modify' && version > 1) {
      try {
        console.log(`[VersionControl] 📥 自动获取上一个版本的内容: ${path}`);
        console.log(`[VersionControl] 当前版本号: v${version}`);
        console.log(`[VersionControl] 期望获取版本: v${version - 1}`);

        actualPreviousContent = await this.getLatestFileContent(projectId, path) || '';

        console.log(`[VersionControl] ✅ 成功获取上一个版本内容`);
        console.log(`[VersionControl] 内容长度: ${actualPreviousContent.length}`);
        console.log(`[VersionControl] 内容预览 (前 200 字符):`, actualPreviousContent.substring(0, 200));
      } catch (error) {
        console.warn(
          `[VersionControl] ⚠️ 无法从历史记录恢复旧内容（补丁可能损坏），将强制创建快照:`,
          error.message,
        );
        actualPreviousContent = '';
        autoForceSnapshot = true; // 🔧 历史记录损坏，自动强制创建快照
      }
    }

    // 🔧 如果没有传 diff，但有 content 和 previousContent，自动生成 diff
    let computedDiff = diff;
    if (!computedDiff && content && actualPreviousContent && action === 'modify') {
      try {
        // 使用 DiffUtils 生成 diff
        const { DiffUtils } = await import('./virtual-file-system/utils/diff');
        computedDiff = DiffUtils.generateDiff(actualPreviousContent, content, path);

        // 📊 调试日志
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        console.log('🔧 [VersionControl] 自动生成 diff');
        console.log('  文件路径:', path);
        console.log('  版本号:', version);
        console.log('  旧内容长度:', actualPreviousContent.length);
        console.log('  新内容长度:', content.length);
        console.log('  旧内容完整:', actualPreviousContent);
        console.log('  新内容完整:', content);
        console.log('  Diff 长度:', computedDiff.length);
        console.log('  Diff 完整内容:', computedDiff);
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
      } catch (error) {
        console.error(`❌ [VersionControl] 生成 diff 失败: ${path}`, error);
      }
    }

    // 决定是否创建快照
    // 1. 首次创建 2. 每10个版本 3. 新增文件 4. 没有 diff（说明是完整内容或无法生成 diff）
    // 5. 🆕 强制创建快照（用于修复损坏的补丁链）
    // 6. 🆕 自动强制快照（历史记录恢复失败时）
    const shouldCreateSnapshot =
      version === 1 ||
      version % 10 === 0 ||
      action === 'add' ||
      !computedDiff ||
      forceSnapshot || // 🆕 手动强制快照标志
      autoForceSnapshot; // 🆕 自动强制快照标志（历史记录损坏时）

    // 🔧 只有在需要创建快照时，才需要 previousContent
    // 如果只是创建补丁（有 diff），不需要 previousContent
    // ⚠️ 如果是强制快照（forceSnapshot 或 autoForceSnapshot = true），说明补丁链已损坏，不要再尝试获取 previousContent
    let previousContent = providedPreviousContent;
    if (
      shouldCreateSnapshot &&
      action === 'modify' &&
      (!previousContent || previousContent === '') &&
      !forceSnapshot && // 🆕 手动强制快照时不要再尝试获取 previousContent
      !autoForceSnapshot // 🆕 自动强制快照时不要再尝试获取 previousContent（历史记录损坏时）
    ) {
      console.log(
        `[VersionControl] 需要创建快照但未提供 previousContent，从数据库获取: ${path}`,
      );
      const latestContent = await this.getLatestFileContent(projectId, path);
      if (latestContent) {
        previousContent = latestContent;
        console.log(
          `[VersionControl] 成功获取 previousContent，长度: ${latestContent.length}`,
        );
      } else {
        console.warn(`[VersionControl] ⚠️ 无法获取 previousContent: ${path}`);
      }
    }

    const changeData: any = {
      projectId,
      path,
      action,
      version,
      timestamp: Date.now(),
      author: author || (await this.getUserName(userId)),
      userId,
      message,
      stats: this.calculateChangeStats(content, previousContent),
      meta: {
        type: 'user',
        source: 'api',
        clientInfo: 'editor',
      },
    };

    if (shouldCreateSnapshot) {
      // 🔧 验证快照内容（删除操作不需要内容）
      if (action !== 'delete' && (!content || content.length === 0)) {
        console.error(
          `[VersionControl] ❌ 需要创建快照但内容为空: ${path} v${version}`,
        );
        throw new BadRequestException(
          `创建快照失败：文件内容为空。请确保前端传递了完整的文件内容（content 字段）。路径: ${path}, 版本: v${version}`,
        );
      }

      // 创建快照：存储完整内容
      changeData.changeType = 'snapshot';
      changeData.content = content;
      changeData.previousContent = previousContent;
      changeData.contentHash =
        contentHash ||
        (content ? this.calculateContentHash(content) : undefined);
      changeData.fileSize = content ? Buffer.byteLength(content, 'utf8') : 0;

      console.log(
        `[VersionControl] ✅ 创建快照: ${path} v${version}, 内容长度: ${content.length}`,
      );
    } else {
      // 创建补丁：使用前端传来的 diff
      const baseSnapshot = await this.findLatestSnapshot(projectId, path);
      if (baseSnapshot) {
        changeData.changeType = 'patch';

        // 🔥 关键修改：优先使用自动生成的 diff，其次使用前端传来的 diff
        if (computedDiff) {
          // ✅ 修复：使用自动生成的 diff（基于 actualPreviousContent）
          changeData.patch = computedDiff;
          changeData.contentHash = contentHash;
          console.log(`[VersionControl] ✅ 使用自动生成的 diff，长度: ${computedDiff.length}`);
        } else if (diff) {
          // 兜底：使用前端传来的 unified diff
          changeData.patch = diff;
          changeData.contentHash = contentHash;
          console.log(`[VersionControl] ✅ 使用前端传来的 diff，长度: ${diff.length}`);
        } else {
          // 兜底：如果没有 diff，使用 actualPreviousContent 生成真正的 unified diff
          console.log(`[VersionControl] ⚠️ 没有可用的 diff，使用 createPatch 生成`);
          changeData.patch = await this.createPatch(
            actualPreviousContent || '', // ✅ 修复：使用 actualPreviousContent 而不是 baseSnapshot.content
            content || '',
            path, // 传入文件路径
          );
          changeData.contentHash = content
            ? this.calculateContentHash(content)
            : undefined;
        }

        // ✅ 修复：baseVersion 应该是上一个版本（version - 1），而不是快照版本
        // 因为补丁是基于上一个版本的内容生成的，而不是基于快照
        changeData.baseVersion = version - 1;
        changeData.fileSize = content ? Buffer.byteLength(content, 'utf8') : 0;
      } else {
        // 如果找不到基础快照，强制创建快照
        // 🔧 验证快照内容（删除操作不需要内容）
        if (action !== 'delete' && (!content || content.length === 0)) {
          console.error(
            `[VersionControl] ❌ 需要强制创建快照但内容为空: ${path} v${version}`,
          );
          throw new BadRequestException(
            `创建快照失败：找不到基础快照且文件内容为空。请确保前端传递了完整的文件内容（content 字段）。路径: ${path}, 版本: v${version}`,
          );
        }

        changeData.changeType = 'snapshot';
        changeData.content = content;
        changeData.previousContent = previousContent;
        changeData.contentHash =
          contentHash ||
          (content ? this.calculateContentHash(content) : undefined);
        changeData.fileSize = content ? Buffer.byteLength(content, 'utf8') : 0;

        console.log(
          `[VersionControl] ✅ 强制创建快照: ${path} v${version}, 内容长度: ${content.length}`,
        );
      }
    }

    const change = await this.fileChangeModel.create(changeData);

    return change.toObject();
  }

  /**
   * 🆕 批量同步文件变更记录
   */
  async syncFileChanges(params: {
    projectId: string;
    changes: Array<{
      path: string;
      action: 'add' | 'modify' | 'delete';
      content?: string;
      previousContent?: string;
      timestamp: number;
      author?: string;
      version: number;
    }>;
    userId: number;
  }): Promise<LcFileChange[]> {
    const { projectId, changes, userId } = params;

    const syncedChanges = [];

    for (const changeData of changes) {
      try {
        // 检查是否已存在相同的变更记录
        const existingChange = await this.fileChangeModel.findOne({
          projectId,
          path: changeData.path,
          timestamp: changeData.timestamp,
          version: changeData.version,
        });

        if (existingChange) {
          // 如果已存在，跳过
          syncedChanges.push(existingChange.toObject());
          continue;
        }

        // 创建新的变更记录
        const contentHash = changeData.content
          ? this.calculateContentHash(changeData.content)
          : undefined;

        const fileSize = changeData.content
          ? Buffer.byteLength(changeData.content, 'utf8')
          : 0;

        const stats = this.calculateChangeStats(
          changeData.content,
          changeData.previousContent,
        );

        const change = await this.fileChangeModel.create({
          projectId,
          path: changeData.path,
          action: changeData.action,
          version: changeData.version,
          timestamp: changeData.timestamp,
          author: changeData.author || (await this.getUserName(userId)),
          userId,
          content: changeData.content,
          previousContent: changeData.previousContent,
          contentHash,
          fileSize,
          stats,
          meta: {
            type: 'sync',
            source: 'migration',
            clientInfo: 'vfs',
          },
        });

        syncedChanges.push(change.toObject());
      } catch (error) {
        console.error(`同步文件变更失败: ${changeData.path}`, error);
        // 继续处理其他变更，不中断整个同步过程
      }
    }

    return syncedChanges;
  }

  /**
   * 查找最新的快照
   */
  private async findLatestSnapshot(
    projectId: string,
    path: string,
  ): Promise<LcFileChange | null> {
    return await this.fileChangeModel
      .findOne({
        projectId,
        path,
        changeType: 'snapshot',
      })
      .sort({ version: -1 })
      .lean();
  }

  /**
   * 创建补丁（使用 unified diff 格式）
   */
  private async createPatch(baseContent: string, newContent: string, filename: string = 'file'): Promise<string> {
    // 使用 DiffUtils 生成真正的 unified diff
    const { DiffUtils } = await import('./virtual-file-system/utils/diff');
    return DiffUtils.generateDiff(baseContent, newContent, filename);
  }

  /**
   * 应用补丁到内容
   */
  private applyPatch(baseContent: string, patchData: string): string {
    try {
      // 尝试解析为 JSON（简化版 diff）
      try {
        const patch = JSON.parse(patchData);
        if (patch.type === 'simple-diff') {
          // 简化版：直接返回新内容
          console.log('[VersionControl] 使用 simple-diff 格式补丁');
          return patch.changes;
        }
      } catch {
        // 不是 JSON，可能是 unified diff
      }

      // 🔧 检查是否是 unified diff 格式
      const isUnifiedDiff =
        patchData.includes('---') && patchData.includes('+++');

      if (!isUnifiedDiff) {
        console.warn('[VersionControl] ⚠️ 补丁格式不是 unified diff，无法应用');
        throw new Error('不支持的补丁格式');
      }

      console.log('[VersionControl] 检测到 unified diff 格式补丁');

      // 🔧 特殊处理：如果基础内容为空且补丁是添加操作，尝试提取新内容
      if (!baseContent || baseContent.length === 0) {
        console.log('[VersionControl] 基础内容为空，尝试从补丁中提取新内容');
        const lines = patchData.split('\n');
        const addedLines = lines
          .filter((line) => line.startsWith('+') && !line.startsWith('+++'))
          .map((line) => line.substring(1));

        if (addedLines.length > 0) {
          console.log(
            `[VersionControl] ✅ 从补丁中提取了 ${addedLines.length} 行新内容`,
          );
          return addedLines.join('\n');
        } else {
          console.warn('[VersionControl] ⚠️ 补丁中没有找到新增内容');
          throw new Error('基础内容为空且补丁中没有新增内容');
        }
      }

      // 🆕 预处理补丁数据，修复常见的格式问题
      const cleanedPatchData = this.cleanPatchData(patchData);

      // 尝试应用 unified diff
      console.log(
        `[VersionControl] 应用 unified diff 到 ${baseContent.length} 字符的基础内容`,
      );
      const result = applyUnifiedPatch(baseContent, cleanedPatchData);

      if (result === false) {
        console.error('[VersionControl] ❌ Unified diff 应用失败');
        console.error('[VersionControl] 基础内容长度:', baseContent.length);
        console.error(
          '[VersionControl] 基础内容预览:',
          baseContent.substring(0, 200),
        );
        console.error(
          '[VersionControl] 补丁预览:',
          cleanedPatchData.substring(0, 500),
        );

        // 🔧 不要尝试恢复策略，直接抛出错误
        // 让调用方决定如何处理（跳过或使用基础内容）
        throw new Error('Unified diff 应用失败');
      }

      console.log(
        `[VersionControl] ✅ Unified diff 应用成功，结果长度: ${result.length}`,
      );
      return result;
    } catch (error) {
      console.error('[VersionControl] 补丁应用异常:', error.message);
      throw error;
    }
  }

  /**
   * 清理补丁数据，修复常见的格式问题
   */
  private cleanPatchData(patchData: string): string {
    let cleaned = patchData;

    // 修复截断的文件路径
    cleaned = cleaned.replace(/^Index: (.+?)([A-Za-z])$/gm, (match, path) => {
      // 如果路径看起来被截断了，尝试修复
      if (path.endsWith('/') || path.length < 10) {
        return match; // 保持原样，可能不是截断
      }
      return match; // 暂时保持原样，需要更多上下文来修复
    });

    // 修复文件路径中的制表符问题
    cleaned = cleaned.replace(/^(---|\+\+\+) (.+?)\t/gm, '$1 $2\t');

    // 确保 hunk 头格式正确
    cleaned = cleaned.replace(
      /^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/gm,
      (_, oldStart, oldCount, newStart, newCount) => {
        const oldC = oldCount || '1';
        const newC = newCount || '1';
        return `@@ -${oldStart},${oldC} +${newStart},${newC} @@`;
      },
    );

    return cleaned;
  }

  /**
   * 尝试多种补丁恢复策略
   */
  private tryPatchRecovery(
    baseContent: string,
    patchData: string,
  ): { success: boolean; content?: string; strategy?: string } {
    // 策略1: 尝试忽略文件路径问题，只处理内容变更
    try {
      const lines = patchData.split('\n');
      const contentLines = lines.filter(
        (line) =>
          !line.startsWith('Index:') &&
          !line.startsWith('===') &&
          !line.startsWith('---') &&
          !line.startsWith('+++'),
      );

      if (contentLines.length > 0) {
        const simplifiedPatch = contentLines.join('\n');
        const result = applyUnifiedPatch(baseContent, simplifiedPatch);
        if (result !== false) {
          return {
            success: true,
            content: result,
            strategy: 'simplified_patch',
          };
        }
      }
    } catch (error) {
      // 策略1失败，继续尝试其他策略
    }

    // 策略2: 如果是纯添加操作，提取所有添加的行
    try {
      const lines = patchData.split('\n');
      const addedLines = lines
        .filter((line) => line.startsWith('+') && !line.startsWith('+++'))
        .map((line) => line.substring(1));

      if (addedLines.length > 0 && baseContent.length === 0) {
        return {
          success: true,
          content: addedLines.join('\n'),
          strategy: 'extract_additions',
        };
      }
    } catch (error) {
      // 策略2失败
    }

    // 策略3: 尝试逐行应用变更
    try {
      const result = this.applyPatchLineByLine(baseContent, patchData);
      if (result) {
        return { success: true, content: result, strategy: 'line_by_line' };
      }
    } catch (error) {
      // 策略3失败
    }

    return { success: false };
  }

  /**
   * 逐行应用补丁（简化版实现）
   */
  private applyPatchLineByLine(
    baseContent: string,
    patchData: string,
  ): string | null {
    try {
      const baseLines = baseContent.split('\n');
      const patchLines = patchData.split('\n');

      const result = [...baseLines];
      let currentLine = 0;

      for (const line of patchLines) {
        if (line.startsWith('@@')) {
          // 解析 hunk 头
          const match = line.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);
          if (match) {
            currentLine = parseInt(match[1]) - 1; // 转换为0基索引
          }
        } else if (line.startsWith('-')) {
          // 删除行
          if (currentLine < result.length) {
            result.splice(currentLine, 1);
          }
        } else if (line.startsWith('+')) {
          // 添加行
          const content = line.substring(1);
          result.splice(currentLine, 0, content);
          currentLine++;
        } else if (line.startsWith(' ')) {
          // 上下文行，跳过
          currentLine++;
        }
      }

      return result.join('\n');
    } catch (error) {
      return null;
    }
  }

  /**
   * 计算内容哈希值
   */
  private calculateContentHash(content: string): string {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const crypto = require('crypto');
    return crypto.createHash('md5').update(content).digest('hex');
  }

  /**
   * 计算变更统计
   */
  private calculateChangeStats(
    content?: string,
    previousContent?: string,
  ): { linesAdded: number; linesDeleted: number; linesModified: number } {
    if (!content && !previousContent) {
      return { linesAdded: 0, linesDeleted: 0, linesModified: 0 };
    }

    if (!previousContent) {
      // 新文件
      const lines = content ? content.split('\n').length : 0;
      return { linesAdded: lines, linesDeleted: 0, linesModified: 0 };
    }

    if (!content) {
      // 删除文件
      const lines = previousContent.split('\n').length;
      return { linesAdded: 0, linesDeleted: lines, linesModified: 0 };
    }

    // 简单的行数对比（实际项目中可以使用更复杂的 diff 算法）
    const currentLines = content.split('\n');
    const previousLines = previousContent.split('\n');

    const added = Math.max(0, currentLines.length - previousLines.length);
    const deleted = Math.max(0, previousLines.length - currentLines.length);
    const modified = Math.min(currentLines.length, previousLines.length);

    return {
      linesAdded: added,
      linesDeleted: deleted,
      linesModified: modified,
    };
  }
}
